import math
import time
import plotly.graph_objects as go

# 初始化参数
human_speed = 10
crocodile_speeds = [20, 20, 15, 20]
side_length = 1000
time_step = 0.05
start_time = time.time()

# 初始化人类位置
human_x = 0
human_y = 0
human_x_history = [human_x]
human_y_history = [human_y]

# 初始化四条鳄鱼位置（正方形四个端点）
crocodiles_x = [-side_length / 2, side_length / 2, side_length / 2, -side_length / 2]
crocodiles_y = [side_length / 2, side_length / 2, -side_length / 2, -side_length / 2]
crocodiles_x_history = [list(crocodiles_x)]
crocodiles_y_history = [list(crocodiles_y)]


def calculate_best_direction():
    """计算最优逃生方向（向量标准化）"""
    escape_vector = [0.0, 0.0]

    for i in range(4):
        # 获取鳄鱼位置和速度
        croc_x = crocodiles_x[i]
        croc_y = crocodiles_y[i]
        croc_speed = crocodile_speeds[i]

        # 计算相对位置向量
        dx = human_x - croc_x
        dy = human_y - croc_y
        distance = math.hypot(dx, dy)

        if distance == 0:
            continue

        # 计算时间权重：鳄鱼到达时间 = 距离/（鳄鱼速度 - 人类速度分量）
        relative_speed = croc_speed - human_speed * (dx / distance)
        if relative_speed <= 0:
            weight = 0
        else:
            time_to_reach = distance / relative_speed
            weight = 1 / (time_to_reach ** 2)  # 时间越短权重越大

        # 累加逃生向量
        escape_vector[0] += dx * weight
        escape_vector[1] += dy * weight

    # 归一化向量
    vec_length = math.hypot(escape_vector[0], escape_vector[1])
    if vec_length == 0:
        return 0, 1  # 默认向上移动
    return (escape_vector[0] / vec_length, escape_vector[1] / vec_length)


def update_positions():
    global human_x, human_y
    # 计算人类移动方向
    direction = calculate_best_direction()
    dx = direction[0] * human_speed * time_step
    dy = direction[1] * human_speed * time_step
    human_x += dx
    human_y += dy
    human_x_history.append(human_x)
    human_y_history.append(human_y)

    # 更新鳄鱼位置
    for i in range(4):
        # 计算指向人类的向量
        dx = human_x - crocodiles_x[i]
        dy = human_y - crocodiles_y[i]
        angle = math.atan2(dy, dx)

        # 移动鳄鱼
        croc_dx = math.cos(angle) * crocodile_speeds[i] * time_step
        croc_dy = math.sin(angle) * crocodile_speeds[i] * time_step
        crocodiles_x[i] += croc_dx
        crocodiles_y[i] += croc_dy
        if len(crocodiles_x_history) <= i:
            crocodiles_x_history.append([crocodiles_x[i]])
            crocodiles_y_history.append([crocodiles_y[i]])
        else:
            crocodiles_x_history[i].append(crocodiles_x[i])
            crocodiles_y_history[i].append(crocodiles_y[i])


# 主循环
while True:
    # 碰撞检测
    for i in range(4):
        if math.hypot(human_x - crocodiles_x[i], human_y - crocodiles_y[i]) < 15:
            # 显示存活时间
            survival_time = time.time() - start_time
            print(f"存活时间: {survival_time:.2f}秒")
            break
    else:
        # 更新位置并保持循环
        update_positions()
        time.sleep(time_step)
        continue
    break

# 使用 Plotly 绘制轨迹
fig = go.Figure()

# 绘制人类轨迹
fig.add_trace(go.Scatter(x=human_x_history, y=human_y_history,
                         mode='lines', name='人类', line=dict(color='blue')))

# 绘制四条鳄鱼轨迹
colors = ['red', 'green', 'orange', 'purple']
for i in range(4):
    fig.add_trace(go.Scatter(x=crocodiles_x_history[i], y=crocodiles_y_history[i],
                             mode='lines', name=f'鳄鱼 {i + 1}', line=dict(color=colors[i])))

# 设置图表布局
fig.update_layout(title='鳄鱼追人模拟 - 动态逃生路径',
                  xaxis_title='X 坐标',
                  yaxis_title='Y 坐标',
                  width=800,
                  height=800)

# 显示图表
fig.show()